import sys
import time
import utils
import xmmsclient
from PyQt4 import QtGui, QtCore
from constants import *
from xmmsclient.collections import *


        

def debug(routine, message=""):
    print >>sys.stderr, "[%s] error! %s" % (routine, message)


class ArtistModel(QtGui.QStandardItemModel):
    def __init__(self, xmms2, parent=None):
        self.xmms2 = xmms2
        QtGui.QStandardItemModel.__init__(self, parent)
        self.setHorizontalHeaderLabels(["Artist"])
        self.xmms2.coll_query_infos(
            Has(Universe(), "artist"),
            ["artist"],
            cb=self.update_model)    

    def update_model(self, res):
        if res.iserror():
            debug("update_model")
            return
        Qentry = [QtGui.QStandardItem("[All]")]
        self.appendRow(Qentry)
        info = res.value()
        for entry in info:
            artist = entry["artist"]
            Qentry = [QtGui.QStandardItem(artist)]
            self.appendRow(Qentry)


class AlbumModel(QtGui.QStandardItemModel):
    def __init__(self, xmms2, parent=None):
        self.xmms2 = xmms2
        QtGui.QStandardItemModel.__init__(self, parent)
        self.setHorizontalHeaderLabels(["Album"])
        self.xmms2.coll_query_infos(
            Has(Universe(), "album"),
            ["album"],
            cb=self.update_model)    

    def update_model(self, res):
        if res.iserror():
            debug("update_model")
            return
        Qentry = [QtGui.QStandardItem("[All]")]
        self.appendRow(Qentry)
        info = res.value()
        for entry in info:
            album = entry["album"]
            Qentry = [QtGui.QStandardItem(album)]
            self.appendRow(Qentry)


class TagsModel(QtGui.QStandardItemModel):
    def __init__(self, xmms2, parent=None):
        self.xmms2 = xmms2
        QtGui.QStandardItemModel.__init__(self, parent)
        self.setHorizontalHeaderLabels(["Track",
                                        "Title",
                                        "Album",
                                        "Artist",
                                        "Id"])
        self.xmms2.coll_query_infos(
            Universe(),
            ["tracknr", "title", "album", "artist", "url", "id"],
            order=["artist", "album", "tracknr", "title"],
            cb=self.update_model)    
    
    def rowActivated(self, index):
        row = index.row()
        print self.item(row, TITLE).text()
    
    def update_model(self, res):
        if res.iserror():
            debug("update_model")
            return
        info = res.value()
        for entry in info:
            _title = entry["title"]
            if _title is None: title = utils.basename(entry["url"])
            else: title = _title
            _tracknr = entry["tracknr"]
            if _tracknr is None: tracknr = u""
            else: tracknr = unicode(_tracknr)
            _album = entry["album"]
            if _album is None: album = u""
            else: album = _album
            _artist = entry["artist"]
            if _artist is None: artist = u""
            else: artist = _artist
            id = entry["id"]
            tracknrEntry = QtGui.QStandardItem(tracknr)
            titleEntry = QtGui.QStandardItem(title)
            albumEntry = QtGui.QStandardItem(album)
            artistEntry = QtGui.QStandardItem(artist)
            idEntry = QtGui.QStandardItem(unicode(id))
            self.appendRow([tracknrEntry,
                            titleEntry,
                            albumEntry,
                            artistEntry,
                            idEntry])

class PlaylistSimpleModel(QtGui.QStandardItemModel):
    _currentPos = 0
    
    def __init__(self, xmms2, playlistName=None):
        QtGui.QStandardItemModel.__init__(self)
        self.setHorizontalHeaderLabels(["Track", "Id"])
        self.xmms2 = xmms2
        self.playlistName = playlistName
        self.format = "%n - %t (%d)\n    %l \n    by %a"
        self.loadPlaylist(playlistName)
        self.xmms2.broadcast_playlist_current_pos(self.currentPos)
        self.xmms2.broadcast_playlist_changed(self.updatePlaylist)

    def currentPos(self, res):
        if res.iserror(): return debug("currentPos", "error!")
        info = res.value()
        position = info["position"]
        playlistName = info["name"]
        item = self.item(self._currentPos)
        font = item.font()
        font.setBold(False)
        item.setFont(font)
        if self.playlistName is not None and self.playlistName != playlistName:
            return
        item = self.item(int(position))
        font = item.font()
        font.setBold(True)
        item.setFont(font)
        self._currentPos = position

    def dropMimeData(self, data, action, row, column, parent):
        #Reimplements drag and drop within the model.
        #Instead of "moving" rows directly, we request the server to do so and
        #then perform the model's rows  permutations according to
        #broadcast_playlist_changed signals. 
         
        if action == QtCore.Qt.IgnoreAction: return False
        if not data.hasFormat(u"text/plain"): return False
        if row != -1: beginRow = row
        elif parent.isValid(): beginRow = parent.row()
        else: beginRow = self.rowCount()
        indexes = [int(i) for i in data.text().split(",")]
        posFlag = 0
        for position in indexes:
            if position < beginRow:
                position += posFlag
                posFlag -= 1
            elif position >= beginRow:
                beginRow += 1
            #print "moving", position, "to", beginRow
            self.xmms2.playlist_move(position, beginRow - 1)
        return True
        
    def loadPlaylist(self, playlistName):
        icon = QtGui.QIcon()
        image = QtGui.QImage()
        pixmap = QtGui.QPixmap()
        def appendToPlaylist(res):
            def setIcon(res):
                if res.iserror(): return debug("loadPlaylist",
                                               "Could not retrieve info!")
                data = res.value()
                image.loadFromData(QtCore.QByteArray(data))
                pixmap2 = pixmap.fromImage(image)
                icon.addPixmap(pixmap2)
                entry = QtGui.QStandardItem(icon, line)
                self.appendRow([entry,
                                QtGui.QStandardItem(id)])
                ####UUUUUUUgly. We must change it!
                try: 
                    self.xmms2.playlist_current_pos(playlistName,
                                                    self.currentPos)
                except:
                    pass
            if res.iserror(): return debug("loadPlaylist",
                                         "Could not retrieve info!")
            info = res.value()
            id = unicode(info["id"])
            line = utils.squeeze(info, self.format)
            try:
                coverHash = info["picture_front"]
                self.xmms2.bindata_retrieve(coverHash, setIcon)
            except KeyError:
                entry = QtGui.QStandardItem(line)
                self.appendRow([entry,
                                QtGui.QStandardItem(id)])
                try: 
                    self.xmms2.playlist_current_pos(playlistName,
                                                self.currentPos)
                except:
                    pass
        def queryInfo(res):
            if res.iserror(): return debug("loadPlaylist",
                                         "Could not query info!")
            for id in res.value():
                self.xmms2.medialib_get_info(id, appendToPlaylist)
        self.xmms2.playlist_list_entries(playlistName, cb=queryInfo)
    
    def mimeData(self, indexes):
        """Returns a QMimeData containing a string with selected rows separated
        by commas.
        """
        mimeData = QtCore.QMimeData()
        draggedRows = ""
        for index in indexes:
            if index.isValid():
                draggedRows = ','.join([draggedRows, unicode(index.row())])
        mimeData.setText(draggedRows[1:])
        return mimeData

    def mimeTypes(self):
        #Our drag and drop is commited by retrieving rows indexes and
        #asking the server to move playlist entries
        return QtCore.QStringList(u"text/plain")

    def updatePlaylist(self, res):
        if res.iserror(): return debug("updatePlaylist")
        info = res.value()
        if self.playlistName is not None and self.playlistName != info["name"]:
            return
        signalType = info["type"]
        if signalType == xmmsclient.PLAYLIST_CHANGED_ADD:
            position = info["position"]
            id = info["id"]
            def addToPlaylist(res):
                if res.iserror(): return debug("addToPlaylist")
                info = res.value()
                line = utils.squeeze(info, self.format)
                self.insertRow(position, [QtGui.QStandardItem(line),
                                          QtGui.QStandardItem(id)])
                if position < self._currentPos: self._currentPos += 1
            self.xmms2.medialib_get_info(id, addToPlaylist)
        elif signalType == xmmsclient.PLAYLIST_CHANGED_REMOVE:
            position = info["position"]
            if self._currentPos > position: self._currentPos -= 1
            self.removeRow(position)
        elif signalType == xmmsclient.PLAYLIST_CHANGED_CLEAR:
            self.clear()
            self._currentPos = 0
        elif signalType == xmmsclient.PLAYLIST_CHANGED_MOVE:
            position = info["position"]
            newPosition = info["newposition"]
            row = self.takeRow(position)
            self.insertRow(newPosition, row)
            
class TagsProxy(QtGui.QSortFilterProxyModel):
    def __init__(self):
        QtGui.QSortFilterModel.__init__(self)
    
